package com.zendaimoney.test.simulation.utils;

import org.apache.commons.lang3.StringUtils;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;

public class JaxbBinder {
    /**
     * 被替换standalone="yes"
     */
    public static String REPLACE_STANDALONE = "standalone=\"yes\"";

    private JAXBContext jaxbContext;

    /**
     * @param types 所有需要序列化的对象的类型
     */
    public JaxbBinder(Class<?>... types) {
        try {
            jaxbContext = JAXBContext.newInstance(types);
        } catch (JAXBException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    /**
     * @param encoding 字符集
     * @return 创建Marshaller
     */
    public Marshaller createMarshaller(String encoding) {
        try {
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
                    Boolean.TRUE);
            if (StringUtils.isNotBlank(encoding)) {
                marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            }
            return marshaller;
        } catch (JAXBException e) {
            throw new RuntimeException();
        }

    }

    /**
     * @return 创建Unmarshaller
     */
    public Unmarshaller createUnMarshaller() {
        try {
            return jaxbContext.createUnmarshaller();
        } catch (JAXBException e) {
            throw new RuntimeException();
        }
    }

    /**
     * 将java对象转换为Xml
     */
    public String toXml(Object obj, String encoding) {
        try {
            StringWriter writer = new StringWriter();
            createMarshaller(encoding).marshal(obj, writer);
            return writer.toString();
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将xml转换为java对象
     */
    @SuppressWarnings("unchecked")
    public <T> T fromXml(String xml) {
        try {
            // StringReader reader = new StringReader(xml);
            // Unmarshaller unmarshaller = createUnMarshaller();
            // return unmarshaller.unmarshal(reader);
            return (T) createUnMarshaller().unmarshal(new StringReader(xml));
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
}
